#pragma once
#include <cstdint>
#include <functional>
class xncc_capture
{
  public:
    xncc_capture();
    explicit xncc_capture(const std::string& if_name);
    ~xncc_capture();
    typedef std::function<void(const char*)> CAP_CALLBACK;
    bool                                     open();
    void                                     receive();
    inline void                              set_callback(CAP_CALLBACK cb)
    {
        cap_cb_ = std::move(cb);
    }

  private:
    void             read_sock_raw(int64_t& index);
    static long long gettimeofday_ms(void);
    bool             ring_poll();
    int              iface_get_mtu(char* ebuf);

  private:
    int                           sock_raw_fd_;
    char*                         buffer_;
    CAP_CALLBACK                  cap_cb_;
    const std::string             bind_interface_;  //绑定网卡
    static constexpr unsigned int NUM_FRAMES        = 4096;
    static constexpr unsigned int COMMON_FRAME_SIZE = 2048;
    unsigned int                  cur_frame_size_   = 0;

    /*
     * When capturing on all interfaces we use this as the buffer size.
     * Should be bigger then all MTUs that occur in real life.
     * 64kB should be enough for now.
     */
    static constexpr unsigned int STABEL_FRAME_SIZE   = 64 * 1024;
    static constexpr unsigned int MAXIMUM_SNAPLEN     = 256 * 1024;
    static constexpr unsigned int MAX_LINKHEADER_SIZE = 256;
    static constexpr unsigned int VLAN_TAG_LEN        = 4;

    static constexpr bool NEED_POLL      = false;
    static constexpr bool BIGGER_ALL_MTU = false;
};
